export enum TaskDataSourceType{
    webFileLink=0,
    webApi=1,
    localFile=2,
    database=3,
}


export enum TaskStep{
    Analysis=1,
    PrepareData=2,
    Train=3,
    Evaluate=4,
    Test=5
}

export class TaskDataSourceTransformRule{
    rule?:Map<string,string>
    constructor(){
        return {}
    }
}

class TaskData<T,K>{
    input:Array<T> = []
    output:Array<K> = []
}

export class TaskDataSource<T,K>{
    datasourceType:TaskDataSourceType = TaskDataSourceType.webFileLink
    datasourceUrl?:string;

    transformRule?:TaskDataSourceTransformRule;
    filters?:Function;//todo use a concrete type,specify the input type and output type
    isWellFormed:boolean = false;

    data?:TaskData<T,K>;
    
    build = ()=> {
        //apply transform rule and filters
        // if()
        //
        this.isWellFormed = true
    }
    updateTransformRule = (rule?:TaskDataSourceTransformRule) => {
        this.transformRule = rule
    }
}

// T is the input Model class, K is the output Model class.
export class Task<T,K>{
    constructor(props:any={}){
        this.name = props.name;
        this.id = props.id;
        this.createtime = props.createtime;
        this.creator = props.creator;
        this.taskStep = props.taskStep||TaskStep.Analysis
    }
    name:string = "";
    id:string = "";
    createtime:string = "";
    creator:string = "";
    trainDataSource?:TaskDataSource<T,K>;
    testDataSource?:TaskDataSource<T,K>;
    taskStep:TaskStep = TaskStep.Analysis;
    modelReport?:string;
    trainDataTransformRule?:TaskDataSourceTransformRule
    tesDataTransformRule?:TaskDataSourceTransformRule

    syncDataToDb = ()=> {
        //sync the train and the test data to database
    }

    updateTrainDataSource = (newTrainDataSource:TaskDataSource<T,K>)=>{
        this.trainDataSource = newTrainDataSource;
    }

    applyRule = ()=> {
        this.trainDataSource?.updateTransformRule(this.trainDataTransformRule)
        this.testDataSource?.updateTransformRule(this.tesDataTransformRule)
    }

    updateTestDataSource = (testDataSource:TaskDataSource<T,K>)=>{
        this.testDataSource = testDataSource;
    }

    getStepDesc = ()=> {
        switch(this.taskStep){
            case TaskStep.Analysis:
                return "Analysis"
            case TaskStep.PrepareData:
                return "Prepare Data"
            case TaskStep.PrepareData:
                return "Train Data"
            case TaskStep.Test:
                return "Test"
            default:
                return "Analysis"
        }
    }


}
